// _functions.scss unit tests
@use '../test_base' as *;
@use '../../src/internal/functions';

/****************
 * hex-to-rgb() *
 ****************/
@include describe('hex-to-rgb()') {
    @include it('should return corresponding rgb color given a hex color') {
        @include assert-equal(functions.hex-to-rgb(#fff), (255, 255, 255));
    }
}

/****************
 * delimitize() *
 ****************/
@include describe('hex-to-rgb()') {
    @include it('should return a string surrounded by the delimiter "-"') {
        @include assert-equal(functions.delimitize('opacity'), '-opacity-');
    }
}

/******************
 * string-split() *
 ******************/
@include describe('string-split()') {
    @include it('should return input string split using delimiter ","') {
        @include assert-equal(functions.string-split('apples,oranges,bananas', ','), ('apples' 'oranges' 'bananas'));
    }
    @include it('should return input string split using delimiter "123"') {
        @include assert-equal(functions.string-split('abc123def', '123'), ('abc' 'def'));
    }
}

/******************
 * map-get-deep() *
 ******************/
@include describe('map-get-deep()') {
    @include it('should return value for key "foo" which is nested 1 level deep') {
        @include assert-equal(
            functions.map-get-deep(
                (
                    foo: bar,
                ),
                'foo'
            ),
            'bar'
        );
    }
    @include it('should return value for key "a.b.c" which is nested 2 levels deep') {
        @include assert-equal(
            functions.map-get-deep(
                (
                    a: (
                        b: (
                            c: 1,
                        ),
                    ),
                ),
                'a.b.c'
            ),
            1
        );
    }
    @include it('should throw error if key does not exist') {
        @include assert-equal(
            functions.map-get-deep(
                (
                    a: (
                        b: (
                            c: 1,
                        ),
                    ),
                ),
                'a.d'
            ),
            build-true-error-string('map-get-strict()', 'ERROR: Specified key "d" does not exist in the mapping')
        );
    }
}

/******************
 * map-get-strict() *
 ******************/
@include describe('map-get-strict()') {
    @include it('should return value for key "foo"') {
        @include assert-equal(
            functions.map-get-strict(
                (
                    foo: bar,
                ),
                'foo'
            ),
            'bar'
        );
    }
    @include it('should throw error if key does not exist') {
        @include assert-equal(
            functions.map-get-strict(
                (
                    foo: bar,
                ),
                'baz'
            ),
            build-true-error-string('map-get-strict()', 'ERROR: Specified key "baz" does not exist in the mapping')
        );
    }
}

/***********************
 * get-with-extended() *
 ***********************/
@include describe('get-with-extend()') {
    @include it('should return default settings for opacity if extend.opacity is empty.') {
        @include assert-equal(
            functions.get-with-extend(
                (
                    opacity: (
                        0: 0,
                        100: 1,
                    ),
                    extend: (
                        opacity: (),
                    ),
                ),
                opacity
            ),
            (
                0: 0,
                100: 1,
            )
        );
    }
    @include it(
        'should return extended settings for opacity if config.opacity is set to null and extended settings is not null.'
    ) {
        @include assert-equal(
            functions.get-with-extend(
                (
                    opacity: null,
                    extend: (
                        opacity: (
                            50: 0.5,
                        ),
                    ),
                ),
                opacity
            ),
            (
                50: 0.5,
            )
        );
    }
    @include it('should return merged original and extended settings if both are not null.') {
        @include assert-equal(
            functions.get-with-extend(
                (
                    opacity: (
                        0: 0,
                        100: 1,
                    ),
                    extend: (
                        opacity: (
                            50: 0.5,
                        ),
                    ),
                ),
                opacity
            ),
            (
                0: 0,
                50: 0.5,
                100: 1,
            )
        );
    }
    @include it('should return empty list if original and extended are null and empty (default) respectively.') {
        @include assert-equal(
            functions.get-with-extend(
                (
                    opacity: null,
                    extend: (
                        opacity: (),
                    ),
                ),
                opacity
            ),
            ()
        );
    }
}

/*********************
 * to-property-map() *
 *********************/
@include describe('to-property-map()') {
    @include it('should return mapping when given a valid list of properties') {
        @include assert-equal(
            functions.to-property-map((left, right, both)),
            (
                left: left,
                right: right,
                both: both,
            )
        );
    }
}

/****************************
 * get-negative-value-map() *
 ****************************/
@include describe('get-negative-value-map()') {
    @include it('should return mapping negated classes when given class mapping of numeric values') {
        @include assert-equal(
            functions.get-negative-value-map(
                (
                    0: 0rem,
                    1: 0.5px,
                    2: 1em,
                    3: 1.5,
                )
            ),
            (
                0: 0rem,
                1: 0.5px,
                n1: -0.5px,
                2: 1em,
                n2: -1em,
                3: 1.5,
                n3: -1.5,
            ),
            // Test fails without this
            $inspect: true
        );
    }

    @include it('should skip creating negative mapping for non-numerical values') {
        @include assert-equal(
            functions.get-negative-value-map(
                (
                    auto: auto,
                    inherit: inherit,
                    unset: unset,
                    5: 5px,
                )
            ),
            (
                auto: auto,
                inherit: inherit,
                unset: unset,
                5: 5px,
                n5: -5px,
            ),
            // Test fails without this
            $inspect: true
        );
    }

    @include it('should skip creating negative mapping for classes with 0 value') {
        @include assert-equal(
            functions.get-negative-value-map(
                (
                    0: 0,
                    zero: 0px,
                )
            ),
            (
                0: 0,
                zero: 0px,
            )
        );
    }
}

/****************
 * strip-unit() *
 ****************/
@include describe('strip-unit()') {
    @include it('should return number without unit for numerical inputs') {
        @include assert-equal(functions.strip-unit(42rem), 42);
        @include assert-equal(functions.strip-unit(42em), 42);
        @include assert-equal(functions.strip-unit(42px), 42);
        @include assert-equal(functions.strip-unit(42), 42);
    }

    @include it('should return same input if not numerical') {
        @include assert-equal(functions.strip-unit(auto), auto);
    }
}

/*********************
 * map-multi-merge() *
 *********************/
@include describe('map-multi-merge()') {
    @include it('should return merged map if we pass in multiple maps as inputs') {
        @include assert-equal(
            functions.map-multi-merge(
                (
                    1: 1,
                ),
                (
                    2: 2,
                    3: 3,
                ),
                (
                    4: 4,
                ),
                (
                    5: 5,
                )
            ),
            (
                1: 1,
                2: 2,
                3: 3,
                4: 4,
                5: 5,
            )
        );
    }
}

/****************
 * map-range() *
 ****************/
@include describe('map-range()') {
    @include it('should return map with numbers only in between given start and end values') {
        @include assert-equal(
            functions.map-range(
                (
                    1: 42,
                    2: 42,
                    3: 42,
                    4: 42,
                    5: 42,
                    6: 42,
                    7: 42,
                    8: 42,
                ),
                2,
                6
            ),
            (
                2: 42,
                3: 42,
                4: 42,
                5: 42,
            )
        );
    }
    @include it('should return map with numbers only in range and non-numeric values') {
        @include assert-equal(
            functions.map-range(
                (
                    1: 42,
                    3: 60,
                    'px': 1,
                ),
                2,
                6,
                true
            ),
            (
                3: 60,
                'px': 1
            )
        );
    }
}
